﻿using System;
using System.Windows.Input;
using Fluffy.Library.Annotations;

namespace Fluffy.Library.Mvvm
{
	public class Command : ICommand
	{
		private readonly Action _method;
		private readonly Func<bool> _canExecuteFunc;

		public event EventHandler CanExecuteChanged;

		public Command(Action method, Func<bool> canExecuteFunc = null)
		{
			if (method == null) 
				throw new ArgumentNullException("method");

			_method = method;
			_canExecuteFunc = canExecuteFunc;
		}

		public bool CanExecute(object parameter)
		{
			return _canExecuteFunc == null || _canExecuteFunc();
		}

		public void Execute(object parameter)
		{
			_method();
		}

		public void RaiseCanExecuteChanged()
		{
			if (CanExecuteChanged != null)
				CanExecuteChanged(this, EventArgs.Empty);
		}
	}

	public class Command<T> : ICommand
	{
		private readonly Action<T> _method;
		private readonly Func<bool> _canExecuteFunc;

		public event EventHandler CanExecuteChanged;

		public Command(Action<T> method, Func<bool> canExecuteFunc = null)
		{
			if (method == null) 
				throw new ArgumentNullException("method");

			_method = method;
			_canExecuteFunc = canExecuteFunc;
		}

		public bool CanExecute(object parameter)
		{
			return _canExecuteFunc == null || _canExecuteFunc();
		}

		public void Execute(object parameter)
		{
			if (parameter == null || parameter is T)
				_method((T)parameter);
		}

		public void RaiseCanExecuteChanged()
		{
			if (CanExecuteChanged != null)
				CanExecuteChanged(this, EventArgs.Empty);
		}
	}
}
